package com.atguigu.tingshu.album.service.impl;

import com.atguigu.tingshu.album.config.VodConstantProperties;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackStatMapper;
import com.atguigu.tingshu.album.service.TrackInfoService;
import com.atguigu.tingshu.album.service.VodService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.common.util.UploadFileUtil;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.album.TrackStat;
import com.atguigu.tingshu.query.album.TrackInfoQuery;
import com.atguigu.tingshu.vo.album.TrackInfoVo;
import com.atguigu.tingshu.vo.album.TrackListVo;
import com.atguigu.tingshu.vo.album.TrackMediaInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qcloud.vod.VodUploadClient;
import com.qcloud.vod.model.VodUploadRequest;
import com.qcloud.vod.model.VodUploadResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class TrackInfoServiceImpl extends ServiceImpl<TrackInfoMapper, TrackInfo> implements TrackInfoService {

	@Autowired
	private TrackInfoMapper trackInfoMapper;

	@Autowired
	private TrackStatMapper trackStatMapper;


	@Autowired
	private AlbumInfoMapper albumInfoMapper;

	@Autowired
	private VodService vodService;

	@Autowired
	private VodConstantProperties vodConstantProperties;

	/**
	 * 修改声音
	 * 修改图片不用更新各种参数，可以考虑从MinIO删除之前的图片。(没有实现)
	 * @param id
	 * @param trackInfoVo
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateTrackInfo(Long id, TrackInfoVo trackInfoVo) {
		//修改声音信息需要修改track_info一张表,但如果修改了声音文件，需要从云点播上删除旧的，添加新的，并把相关参数保存
		TrackInfo trackInfo = trackInfoMapper.selectById(id);
		//不相等，说明上传了新的声音
		if(!trackInfo.getMediaFileId().equals(trackInfoVo.getMediaFileId())){
			//删除旧的，这里的参数需要是旧的FileId
			vodService.deleteMedia(trackInfo.getMediaFileId());
			//获取新的，这里的参数需要是新的FileId
			TrackMediaInfoVo mediaInfo = vodService.getMediaInfo(trackInfoVo.getMediaFileId());
			trackInfo.setMediaSize(mediaInfo.getSize());
			trackInfo.setMediaDuration(mediaInfo.getDuration());
			trackInfo.setMediaUrl(mediaInfo.getMediaUrl());
			trackInfo.setMediaType(mediaInfo.getType());
		}
		BeanUtils.copyProperties(trackInfoVo,trackInfo);
		//保存数据
		trackInfoMapper.updateById(trackInfo);
	}

	/**
	 * 根据声音id回显数据
	 * @param id
	 * @return
	 */
	@Override
	public TrackInfo  getTrackInfo(Long id) {
		TrackInfo trackInfo = trackInfoMapper.selectById(id);

		return trackInfo;
	}

	/**
	 * 根据id删除声音
	 * @param id
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void removeTrackInfo(Long id) {
		//删除声音需要删除两张表track_info和track_stat,修改一张表album_info里的专辑声音数量字段。还需要从云点播删除声音
		//删除track_info表的数据,删除之后其他序号比该声音大的声音序号要减1
		TrackInfo trackInfo = trackInfoMapper.selectById(id);
		Integer orderNum = trackInfo.getOrderNum();
		//删除该声音，修改当前专辑其他声音的order_num
		trackInfoMapper.deleteById(id);
		trackInfoMapper.updateOrderNum(orderNum,trackInfo.getAlbumId());

		//删除track_stat表的数据
		trackStatMapper.delete(new LambdaQueryWrapper<TrackStat>()
				.eq(TrackStat::getTrackId,id));

		//修改album_info表的声音数量字段
		AlbumInfo albumInfo = albumInfoMapper.selectById(trackInfo.getAlbumId());
		albumInfo.setIncludeTrackCount(albumInfo.getIncludeTrackCount()-1);
		albumInfoMapper.updateById(albumInfo);

		//从云点播删除声音
		vodService.deleteMedia(trackInfo.getMediaFileId());

	}

	@Override
	public Page<TrackListVo> findUserTrackPage(Page<TrackListVo> trackListVoPage, TrackInfoQuery trackInfoQuery) {
		return trackInfoMapper.selectUserTrackPage(trackListVoPage,trackInfoQuery);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void saveTrackInfo(Long userId, TrackInfoVo trackInfoVo) {
		//保存需要考虑的表。track_info声音信息表、track_stat声音统计表、album_info中的拥有声音数量字段
		//组装声音信息实体类对象
		TrackInfo trackInfo = new TrackInfo();
		BeanUtils.copyProperties(trackInfoVo,trackInfo);
		trackInfo.setUserId(userId);

		TrackInfo trackInfoQuery = trackInfoMapper.selectOne(new LambdaQueryWrapper<TrackInfo>()
				.eq(TrackInfo::getAlbumId, trackInfo.getAlbumId())
				.select(TrackInfo::getOrderNum)
				.orderByDesc(TrackInfo::getOrderNum)
				.last("limit 1"));
		trackInfo.setOrderNum(trackInfoQuery==null?1:trackInfoQuery.getOrderNum()+1);
		//组装上传的声音文件的信息，大小、长度、类型等
		TrackMediaInfoVo trackMediaInfoVo = vodService.getMediaInfo(trackInfo.getMediaFileId());
		trackInfo.setMediaDuration(trackMediaInfoVo.getDuration());
		trackInfo.setMediaSize(trackMediaInfoVo.getSize());
		trackInfo.setMediaType(trackMediaInfoVo.getType());
		trackInfo.setMediaUrl(trackMediaInfoVo.getMediaUrl());

		//插入声音信息表
		trackInfoMapper.insert(trackInfo);

		//插入声音统计表
		saveTrackStat(trackInfo.getId(),SystemConstant.TRACK_STAT_PLAY);
		saveTrackStat(trackInfo.getId(),SystemConstant.TRACK_STAT_COLLECT);
		saveTrackStat(trackInfo.getId(),SystemConstant.TRACK_STAT_PRAISE);
		saveTrackStat(trackInfo.getId(),SystemConstant.TRACK_STAT_COMMENT);

		//修改album_info中的拥有声音数量字段
		AlbumInfo albumInfo = albumInfoMapper.selectById(trackInfo.getAlbumId());
		albumInfo.setIncludeTrackCount(albumInfo.getIncludeTrackCount()+1);
		albumInfoMapper.updateById(albumInfo);

	}

	private void saveTrackStat(Long trackId,String type) {
		TrackStat trackStat = new TrackStat();
		trackStat.setTrackId(trackId);
		trackStat.setStatType(type);
		trackStat.setStatNum(0);
		trackStatMapper.insert(trackStat);
	}

	/**
	 *上传声音
	 * @param file
	 * @return
	 */
	@Override
	public Map<String,Object> uploadTrack(MultipartFile file) {
		//  声音上传临时目录：
		String tempPath = UploadFileUtil.uploadTempPath(vodConstantProperties.getTempPath(), file);
		//  创建上传声音客户端
		VodUploadClient client = new VodUploadClient(vodConstantProperties.getSecretId()
				, vodConstantProperties.getSecretKey());
		//构造上传请求对象
		VodUploadRequest request = new VodUploadRequest();
		//  设置视频本地地址
		request.setMediaFilePath(tempPath);
		//调用上传
		try {
			VodUploadResponse response = client.upload(vodConstantProperties.getRegion(), request);
			//  创建map 对象
			HashMap<String, Object> map = new HashMap<>();
			map.put("mediaFileId",response.getFileId());
			map.put("mediaUrl",response.getMediaUrl());
			log.info("Upload FileId = {}", response.getFileId());
			//  返回map 数据
			return map;

		} catch (Exception e) {
			// 业务方进行异常处理
			throw new GuiguException(ResultCodeEnum.FAIL);
		}

	}

}
